#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: deprecated_app.py
# @time: 2021/3/23 16:59
# @desc:
import json

import asyncio
from fastapi import APIRouter, File, UploadFile, Request

from application.history_part.crud import keyword_search_history_part, list_query_redis_cache, generate_history_part_data
from application.history_part.queryModel import UploadHistoryPartModel, HistoryPartImageModel
from models.models import PartTag
from models.queryModels import MultipleConditionQueryHistoryParts, UpdateHistoryPartConfigData, LockFlagQuery
from models.responseModels import ResponseDict
from utils.mongo_tools import create_one_mongo_value, delete_mongo_value, retrieve_one_mongo_value, retrieve_all_mongo_values, update_mongo_value, total_number_generator, history_part_number_generator
from utils.utils import create_folder, write_file
from views.configs import *
from views.configs import HISTORY_PART_COLLECTION
from views.crud import upload_to_aliyun_part_model, separate_page, send_to_message_queue

deprecated_history_part_router = APIRouter(
    # prefix="/api/standard_part",
    prefix="/api/history_part",
    tags=["history_part"],
)


@deprecated_history_part_router.post("/v1/history_part_catia_file")
async def upload_history_part_catia_file(file: UploadFile = File(...)):
    """
    TODO: 这里接收用户上传的文件，返回上传是否成功，以及上传的文件唯一id（Number）。

    - :param file:
    - :return:
    """
    isFeature: bool = False
    isFlag: bool = False
    desc = ""
    version = "2.0"
    folder = create_folder()
    file_path = f"{folder}/{file.filename}"
    # print(file_path)

    write_file(file_path=file_path, file=file)
    model = {}
    try:
        # 上传至阿里云
        historyPart = upload_to_aliyun_part_model(
            filename=file_path,
            desc=desc,
            version=version,
            isFeature=isFeature,
            isFlag=isFlag,
        )
        model["data"] = historyPart["number"]
        model["status"] = 1

        create_one_mongo_value(
            new_value=historyPart,
            database_name=MONGO_DATABASE_NAME,
            collection_name=HISTORY_PART_COLLECTION,
        )
    except:
        model["status"] = 0
    return model


@deprecated_history_part_router.get("/v1/history_parts")
async def retrieve_history_part(request: Request):
    """

    - :return:
    """
    keys = await request.app.state.redis.keys("202102[0-9]*")
    # print(keys)
    data = await request.app.state.redis.mget(*keys)
    # data = await request.app.state.redis.mget("202102[0-9]*")
    data = [json.loads(i) for i in data]

    return data


@deprecated_history_part_router.post("/v1/history_parts", response_model=ResponseDict)
async def multiple_condition_query_history_parts(request: Request, queryModel: MultipleConditionQueryHistoryParts):
    """
    列表查询多条历史零件。输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    model = {"data": {"result": []}}

    result = []
    # 先把redis中的符合历史夹具的key都拿出来
    try:
        history_part_number_list = await request.app.state.redis.keys("202102[0-9]*")
        history_part = await request.app.state.redis.mget(*history_part_number_list)
        for i in history_part:
            if "_pop" in i.keys():
                i.pop("_id")
            result.append(json.loads(i))
    except:
        result = retrieve_all_mongo_values({}, collection_name=HISTORY_PART_COLLECTION)
        for i in result:
            await request.app.state.redis.set(i["number"], json.dumps(i))

    result = keyword_search_history_part(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:
        if not queryModel.isTotal:
            model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            model["data"]["result"] = result
    model["status"] = 1
    return model


@deprecated_history_part_router.get("/v2/history_parts")
async def retrieve_history_part_v2():
    """
    ## Deprecated
    ## 测试使用索引后是否会提速。

    - :return:
    """
    data = retrieve_all_mongo_values({}, collection_name=HISTORY_PART_COLLECTION)

    return data


@deprecated_history_part_router.delete("/v1/history_part")
async def delete_history_part(request: Request, number: str):
    """
    根据零件的编号删除历史零件（一次删除单条数据）

    - :param number:
    - :return:
    """
    try:
        await request.app.state.redis.delete(number)
    except:
        pass

    model = {"data": False}
    try:
        result = delete_mongo_value(
            number=number,
            database_name=MONGO_DATABASE_NAME,
            collection_name=HISTORY_PART_COLLECTION
        )
        if result.deleted_count > 0:
            model["data"] = True
            model["status"] = 1
        else:
            model["status"] = 0
    except:
        model["status"] = 0
    return model


@deprecated_history_part_router.get("/v1/history_part_config")
async def retrieve_history_part_config(request: Request):
    """
    ## 获取历史零件config标签属性v1版

    - :return:
    """
    try:
        history_part_config = await request.app.state.redis.get("history_part_config")
        history_part_config = json.loads(history_part_config)
    except:
        history_part_config = retrieve_all_mongo_values({"type": CONFIG_DATA_HISTORY_PART_TYPE}, collection_name=CONFIG_COLLECTION)[0]
        await request.app.state.redis.set("history_part_config", json.dumps(history_part_config))

    model = {"data": history_part_config, "status": 1}
    return model


@deprecated_history_part_router.put("/v1/history_part_image")
async def update_history_part_image(request: Request, queryModel: HistoryPartImageModel):
    """
    ## 添加/更新历史零件缩略图

    - :return:
    """
    try:
        await request.app.state.redis.delete(queryModel.number)
    except:
        pass

    history_part = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_PART_COLLECTION)[0]
    history_part["imgUrl"] = queryModel.imgUrl
    updateInfo = {"$set": history_part}
    update_mongo_value(
        filter_condition={"number": queryModel.number},
        new_value=updateInfo,
        collection_name=HISTORY_PART_COLLECTION,
    )
    await request.app.state.redis.set(queryModel.number, json.dumps(history_part))
    model = {"data": True, "status": 1}
    return model


@deprecated_history_part_router.post("/v3/history_part")
async def upload_v3(request: Request, queryModel: UploadHistoryPartModel):
    """
    上传历史零件的catpart格式文件并转化stp, stl, glb的接口，前端传过来的只有夹具）的OSS地址，这里需要在数据库里生成一条数据，把这些地址存到这条数据里。

    - :return:
    """
    data = []
    for i in queryModel.catpartAliOssAddress:
        number = history_part_number_generator()
        partModel = generate_history_part_data(
            number,
            file_path=i,
            version=queryModel.version,
        )
        if queryModel.standard is not None:
            partModel["tag"]["standard"].append(queryModel.standard)

        await request.app.state.redis.set(partModel["number"], json.dumps(partModel))

        create_one_mongo_value(partModel, collection_name=HISTORY_PART_COLLECTION)
        send_to_message_queue(number)
        data.append(number)

    # 需要在redis的history_part键里添加这几个number
    history_part_number_list = await request.app.state.redis.get("history_part")
    history_part_number_list = json.loads(history_part_number_list)
    history_part_number_list.extend(data)
    await request.app.state.redis.set("history_part", json.dumps(history_part_number_list))
    model = {"data": data, "status": 1}
    return model


@deprecated_history_part_router.put("/v1/history_part")
async def update_history_part(request: Request, queryModel: PartTag):
    """
    修改历史零件标签属性，

    - :param queryModel: 要更新的零件的信息
    - :return:
    """
    try:
        await request.app.state.redis.delete(queryModel.number)
    except:
        pass

    tag = retrieve_all_mongo_values(
        {"number": queryModel.number},
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )[0]['tag']
    if queryModel.bigType is not None:
        tag['bigType'] = queryModel.bigType
    if queryModel.category is not None:
        tag['category'] = queryModel.category
    if len(queryModel.standard) > 0:
        tag['standard'] = queryModel.standard
    if queryModel.smallType is not None:
        tag['smallType'] = queryModel.smallType
    tag['elseTag'] = queryModel.elseTag
    updateInfo = {"$set": {"tag": tag}}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )
    partModel = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_PART_COLLECTION)[0]
    await request.app.state.redis.set(queryModel.number, json.dumps(partModel))

    model = {"data": True, "status": 1}
    return model


@deprecated_history_part_router.put("/v2/history_part")
async def update_history_part_v2(request: Request, queryModel: PartTag):
    """
    ## 修改历史零件标签属性，

    - :param queryModel: 要更新的零件的信息
    - :return:
    """
    try:
        await request.app.state.redis.delete(queryModel.number)
    except:
        pass

    tag = retrieve_all_mongo_values(
        {"number": queryModel.number},
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )[0]['tag']
    if queryModel.version is not None:
        tag['version'] = queryModel.version
    if queryModel.pillarHeight is not None:
        tag['pillarHeight'] = queryModel.pillarHeight
    if queryModel.bigType is not None:
        tag['bigType'] = queryModel.bigType
    if queryModel.category is not None:
        tag['category'] = queryModel.category
    if len(queryModel.standard) > 0:
        tag['standard'] = queryModel.standard
    if queryModel.smallType is not None:
        tag['smallType'] = queryModel.smallType
    tag['elseTag'] = queryModel.elseTag
    updateInfo = {"$set": {"tag": tag}}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )
    partModel = retrieve_one_mongo_value(queryModel.number, collection_name=HISTORY_PART_COLLECTION)[0]
    await request.app.state.redis.set(queryModel.number, json.dumps(partModel))

    model = {"data": True, "status": 1}
    return model


@deprecated_history_part_router.get("/v2/history_part_drop_down_box")
async def get_history_part_drop_down_box_v2():
    """
    ## 历史零件下拉框数据v2。

    - :return:
    """
    model = {"data": {}}

    # result = await request.app.state.redis.get("history_part_config")
    # result = json.loads(result)
    result = retrieve_all_mongo_values(
        {"type": CONFIG_DATA_HISTORY_PART_TYPE},
        collection_name=CONFIG_COLLECTION,
    )[0][CONFIG_DATA]

    model["data"] = result
    model["status"] = 1
    return model


@deprecated_history_part_router.put("/v2/history_part_config")
async def update_history_part_config_v2(request: Request, oneInfo: UpdateHistoryPartConfigData):
    """
    ## 修改历史零件config标签属性v2版

    - :return:
    """
    try:
        await request.app.state.redis.delete("history_part_config")
    except:
        pass

    config_data = retrieve_all_mongo_values(
        {"type": CONFIG_DATA_HISTORY_PART_TYPE},
        collection_name=CONFIG_COLLECTION
    )[0][CONFIG_DATA]
    if oneInfo.standard is not None:
        config_data['standard'] = oneInfo.standard
    if oneInfo.partType is not None:
        config_data['partType'] = oneInfo.partType
    if oneInfo.version is not None:
        config_data['version'] = oneInfo.version
    updateInfo = {"$set": {"configData": config_data}}
    update_mongo_value(
        filter_condition={"type": CONFIG_DATA_HISTORY_PART_TYPE},
        new_value=updateInfo,
        collection_name=CONFIG_COLLECTION,
    )
    config_data = retrieve_all_mongo_values({"type": CONFIG_DATA_HISTORY_PART_TYPE}, collection_name=CONFIG_COLLECTION)[0][CONFIG_DATA]
    await request.app.state.redis.set("history_part_config", json.dumps(config_data))
    model = {"data": True, "status": 1}
    return model


# @history_part_router.get("/v3/history_part_drop_down_box")
# def get_history_part_drop_down_box_v2():
#     """
#     ## 历史零件下拉框数据v3。
#
#     - :return:
#     """
#     redis_connection = get_redis(port=HISTORY_PART_REDIS_PORT)
#     try:
#         history_part_config = redis_connection.get("history_part_config")
#         config_data = json.loads(history_part_config)
#     except:
#         config_data = retrieve_all_mongo_values(
#             {"type": CONFIG_DATA_HISTORY_PART_TYPE},
#             collection_name="config",
#         )[0][CONFIG_DATA]
#         # 把mongo中查到的数据set到redis数据库中
#         redis_connection.set("history_part_config", json.dumps(config_data))
#
#     model = {"data": config_data, "status": 1}
#     return model


@deprecated_history_part_router.get("/v1/history_part_drop_down_box")
async def get_history_part_drop_down_box():
    """
    ## Deprecated
    ## 历史零件下拉框数据。注意请求原来是POST，现在改为GET了。

    - :return:
    """
    model = {"data": {}}

    result = retrieve_all_mongo_values(
        {"type": "part"},
        database_name=MONGO_DATABASE_NAME,
        collection_name="config",
    )[0]['configData']

    model["data"] = result
    model["status"] = 1
    return model


@deprecated_history_part_router.put("/v1/history_part_config")
async def update_history_part_config(request: Request, oneInfo: UpdateHistoryPartConfigData):
    """
    ## Deprecated
    ## 修改历史零件config标签属性

    - :return:
    """
    try:
        await request.app.state.redis.delete("history_part_config")
    except:
        pass

    config_data = retrieve_all_mongo_values(
        {"type": "standardPart"},
        database_name=MONGO_DATABASE_NAME,
        collection_name="config"
    )[0]['configData']
    if oneInfo.standard is not None:
        config_data['standard'] = oneInfo.standard
    if oneInfo.partType is not None:
        config_data['partType'] = oneInfo.partType
    updateInfo = {"$set": {"configData": config_data}}
    update_mongo_value(
        {"type": "standardPart"},
        updateInfo,
        database_name=MONGO_DATABASE_NAME,
        collection_name="config",
    )
    config_data = retrieve_all_mongo_values({"type": "standardPart"}, database_name=MONGO_DATABASE_NAME, collection_name="config")[0]['configData']
    await request.app.state.redis.set("history_part_config", json.dumps(config_data))
    model = {"data": True, "status": 1}
    return model


@deprecated_history_part_router.post("/v2/history_part")
async def upload(request: Request, queryModel: UploadHistoryPartModel):
    """
    ## Deprecated
    上传历史零件的catpart格式文件并转化stp, stl, glb的接口，前端传过来的只有夹具）的OSS地址，这里需要在数据库里生成一条数据，把这些地址存到这条数据里。

    - :return:
    """
    number = history_part_number_generator()
    partModel = generate_history_part_data(
        number,
        file_path=queryModel.catpartAliOssAddress,
    )

    await request.app.state.redis.set(partModel["number"], json.dumps(partModel))

    create_one_mongo_value(partModel, collection_name=HISTORY_PART_COLLECTION)
    send_to_message_queue(number)

    model = {"data": number, "status": 1}
    return model


@deprecated_history_part_router.get("/v1/history_part")
async def retrieve_history_part(number: str):
    """
    返回一条历史零件的完整信息

    - :param number: 编号
    - :return:
    """
    model = {"data": {}}
    original_data = retrieve_one_mongo_value(number, database_name=MONGO_DATABASE_NAME, collection_name=HISTORY_PART_COLLECTION)
    try:
        model["data"] = original_data[0]
        model["status"] = 1
    except IndexError:
        model["status"] = 0
    return model


@deprecated_history_part_router.post("/v2/history_parts", response_model=ResponseDict)
async def multiple_condition_query_history_parts(request: Request, queryModel: MultipleConditionQueryHistoryParts):
    """
    列表查询多条历史零件。输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    model = {"data": {"result": []}}

    # 先把redis中的符合历史夹具的key都拿出来
    try:
        history_part_number_list = await request.app.state.redis.get("history_part")
        history_part_number_list = json.loads(history_part_number_list)
        history_part = await request.app.state.redis.mget(*history_part_number_list)
        result = [json.loads(i) for i in history_part]
    except:
        result = retrieve_all_mongo_values({}, collection_name=HISTORY_PART_COLLECTION)
        for i in result:
            await request.app.state.redis.set(i["number"], json.dumps(i))

    result = keyword_search_history_part(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:
        if not queryModel.isTotal:
            model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            model["data"]["result"] = result
    model["status"] = 1
    return model


@deprecated_history_part_router.put("/v1/history_part_flag_tag")
async def update_history_part_flag_tag(request: Request, queryModel: LockFlagQuery):
    """
    锁定零件状态

    - :param number:
    - :param isFlag:
    - :return:
    """
    try:
        await request.app.state.redis.delete(queryModel.number)
    except:
        pass

    update_mongo_value(
        filter_condition={"number": queryModel.number},
        new_value={"$set": {"isFlag": queryModel.isFlag}},
        database_name=MONGO_DATABASE_NAME,
        collection_name=HISTORY_PART_COLLECTION,
    )
    model = {
        "status": 1,
        "data": True,
    }
    return model
